#include <iostream>
#include <string>
#include <memory>

/*抽象产品类*/
class Computer
{
public:
    void SetBoard(const std::string &board)
    {
        _board = board;
    }

    void SetDisplay(const std::string &display)
    {
        _display = display;
    }

    virtual void SetOS() = 0;

    void show()
    {
        std::string computer = "Computer:{\n";
        computer += "\tboard=" + _board + ",\n";
        computer += "\tdisplay=" + _display + ",\n";
        computer += "\tOs=" + _OS + ",\n";
        computer += "}\n";
        
        std::cout << computer << std::endl;
    }

protected:
    std::string _display;
    std::string _board;
    std::string _OS;
};
/*具体产品类*/
class WinBook : public Computer
{
public:
    void SetOS()
    {
        _OS = "Win11";
    }
};
/*抽象建造者类*/
class Builder
{
public:
    Builder() {}
    virtual void BuildBoard(const std::string& board) = 0;
    virtual void BuildDisplay(const std::string& display) = 0;
    virtual void BuildOS() = 0;
    virtual std::shared_ptr<Computer> build() = 0;
};
/*具体抽象类*/
class WinbookBuilder : public Builder
{
public:
    WinbookBuilder() 
        : _computer(new WinBook())
    {}

    void BuildBoard(const std::string& board)
    {
        _computer->SetBoard(board);
    }

    void BuildDisplay(const std::string& display)
    {
        _computer->SetDisplay(display);
    }

    void BuildOS()
    {
        _computer->SetOS();
    }

    std::shared_ptr<Computer> build()
    {
        return _computer;
    }
private:
    std::shared_ptr<Computer> _computer;
};
/*指挥者类*/
class Director
{
public:
    Director(Builder* builder)
        : _builder(builder)
    {}

    void Construct(const std::string& board, const std::string& display)
    {
        _builder->BuildBoard(board);
        _builder->BuildDisplay(display);
        _builder->BuildOS();
    }
private:
    Builder* _builder;
};

int main()
{
    Builder* builder = new WinbookBuilder();
    std::shared_ptr<Director> director(new Director(builder));
    director->Construct("英特尔主板", "华硕显示器");
    std::shared_ptr<Computer> computer = builder->build();
    computer->show();
    
    return 0;
}